কম্পোজিট কী (Composite Key) হলো একাধিক কলাম বা ফিল্ডের সমন্বয়ে তৈরি একটি প্রাইমারি কী। এটি তখন ব্যবহার করা হয় যখন একটি টেবিলের একক কলাম প্রাইমারি কী হিসেবে পর্যাপ্ত নয়। Hibernate বা JPA এর মাধ্যমে স্প্রিং ORM এ কম্পোজিট কী পরিচালনা করা সম্ভব।
Hibernate বা JPA এর মাধ্যমে কম্পোজিট কী ব্যবহারের জন্য @EmbeddedId
বা @IdClass
এনোটেশন ব্যবহার করা হয়।
@EmbeddedId
ব্যবহার করে একটি পৃথক Embeddable ক্লাস তৈরি করা হয় যা প্রাইমারি কী হিসাবে ব্যবহৃত হয়।
Step 1: Embeddable ক্লাস তৈরি
package com.example.model;
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class CompositeKey implements Serializable {
private int orderId;
private int productId;
// Getters, Setters, hashCode, equals
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
@Override
public int hashCode() {
return orderId + productId;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
CompositeKey that = (CompositeKey) obj;
return orderId == that.orderId && productId == that.productId;
}
}
Step 2: Entity ক্লাস তৈরি
package com.example.model;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
@Entity
public class OrderProduct {
@EmbeddedId
private CompositeKey id;
private int quantity;
// Getters and Setters
public CompositeKey getId() {
return id;
}
public void setId(CompositeKey id) {
this.id = id;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
@IdClass
ব্যবহার করে একটি পৃথক ক্লাস তৈরি করা হয় যা প্রাইমারি কী ধারণ করে এবং @Id
এনোটেশন Entity ক্লাসের মধ্যে প্রত্যেক কী ফিল্ডে যোগ করা হয়।
Step 1: Composite Key ক্লাস তৈরি
package com.example.model;
import java.io.Serializable;
public class CompositeKey implements Serializable {
private int orderId;
private int productId;
// Getters, Setters, hashCode, equals
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
@Override
public int hashCode() {
return orderId + productId;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
CompositeKey that = (CompositeKey) obj;
return orderId == that.orderId && productId == that.productId;
}
}
Step 2: Entity ক্লাস তৈরি
package com.example.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
@Entity
@IdClass(CompositeKey.class)
public class OrderProduct {
@Id
private int orderId;
@Id
private int productId;
private int quantity;
// Getters and Setters
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
DAO স্তরে Hibernate বা JPA এর মাধ্যমে কম্পোজিট কী ব্যবহার করে ডেটা ম্যানিপুলেট করা যায়।
package com.example.dao;
import com.example.model.OrderProduct;
import com.example.model.CompositeKey;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class OrderProductDao {
@Autowired
private SessionFactory sessionFactory;
public void saveOrderProduct(OrderProduct orderProduct) {
Session session = sessionFactory.getCurrentSession();
session.save(orderProduct);
}
public OrderProduct getOrderProduct(CompositeKey id) {
Session session = sessionFactory.getCurrentSession();
return session.get(OrderProduct.class, id);
}
}
@EmbeddedId
এবং @IdClass
এর মধ্যে পার্থক্য:@EmbeddedId
: কম্পোজিট কী সম্পূর্ণ Embeddable অবজেক্ট হিসেবে ব্যবহৃত হয়।@IdClass
: কম্পোজিট কী-এর জন্য একটি পৃথক ক্লাস তৈরি করা হয় এবং Entity ক্লাসে প্রত্যেক কী কলাম আলাদাভাবে সংজ্ঞায়িত থাকে।hashCode
এবং equals
মেথড ওভাররাইড করতে হবে।স্প্রিং ওআরএম এর মাধ্যমে Hibernate ব্যবহার করে কম্পোজিট কী পরিচালনা করা সহজ এবং কার্যকর। @EmbeddedId
এবং @IdClass
দুটি পদ্ধতির মাধ্যমে কম্পোজিট কী কার্যকর করা যায়।
Composite Key হলো একটি প্রাইমারি কী (Primary Key), যা একাধিক কলামের (fields/attributes) সমন্বয়ে গঠিত। সাধারণত যখন কোনো একক কলাম ডেটাবেস টেবিলে একটি ইউনিক রেকর্ড সনাক্ত করার জন্য যথেষ্ট নয়, তখন Composite Key ব্যবহার করা হয়। এটি একটি ইউনিক পরিচয় নিশ্চিত করতে একাধিক কলামের মান একত্রে ব্যবহার করে।
Composite Key নিম্নলিখিত ক্ষেত্রে ব্যবহার করা হয়:
JPA এবং Hibernate-এ Composite Key তৈরির জন্য @Embeddable এবং @EmbeddedId এনোটেশন ব্যবহার করা হয়।
@Embeddable
public class OrderId implements Serializable {
private Long orderId;
private Long productId;
// Default Constructor
public OrderId() {}
// Getters and Setters
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
// hashCode and equals methods
@Override
public int hashCode() {
return Objects.hash(orderId, productId);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
OrderId that = (OrderId) obj;
return Objects.equals(orderId, that.orderId) &&
Objects.equals(productId, that.productId);
}
}
@Entity
public class Order {
@EmbeddedId
private OrderId id;
private int quantity;
// Getters and Setters
public OrderId getId() {
return id;
}
public void setId(OrderId id) {
this.id = id;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
Composite Key সংজ্ঞায়িত করতে @IdClass ব্যবহার করা হয়। এই পদ্ধতিতে, একটি সেপারেট ক্লাস Primary Key হিসাবে সংজ্ঞায়িত হয়।
public class OrderId implements Serializable {
private Long orderId;
private Long productId;
// Default Constructor
public OrderId() {}
// Getters and Setters, hashCode and equals methods
}
@Entity
@IdClass(OrderId.class)
public class Order {
@Id
private Long orderId;
@Id
private Long productId;
private int quantity;
// Getters and Setters
}
স্প্রিং ORM JPA এর @EmbeddedId এবং @IdClass এর মাধ্যমে Composite Key পরিচালনার সহজ এবং কার্যকর উপায় প্রদান করে। এটি ডেভেলপারদের ডেটাবেসের জটিল সম্পর্ক সহজে মডেল করতে সাহায্য করে এবং স্প্রিং এর ডেটা অ্যাক্সেস লেয়ারকে আরও শক্তিশালী করে তোলে।
Spring ORM বা Hibernate-এ @Embeddable এবং @EmbeddedId অ্যানোটেশন ব্যবহার করা হয় কম্পোজিট প্রাইমারি কি (Composite Primary Key) পরিচালনার জন্য। যখন কোনো ডাটাবেস টেবিলের জন্য একাধিক কলাম একসঙ্গে প্রাইমারি কি হিসেবে ব্যবহৃত হয়, তখন এই অ্যানোটেশনগুলো কার্যকর ভূমিকা পালন করে।
@Embeddable অ্যানোটেশন একটি জাভা ক্লাসকে নির্দেশ করে যে এটি অন্য কোনো Entity-তে এম্বেড করা যাবে। এই ক্লাস সাধারণত কম্পোজিট প্রাইমারি কি বা অন্য কোনো এম্বেডেড ডেটার জন্য ব্যবহৃত হয়।
@Embeddable
public class EmployeeId {
private int departmentId;
private int employeeNumber;
// Getters, Setters, hashCode, and equals মেথড
}
@EmbeddedId অ্যানোটেশন একটি Entity-তে কম্পোজিট প্রাইমারি কি ব্যবহার করতে সাহায্য করে। এটি @Embeddable দ্বারা নির্ধারিত ক্লাসকে এম্বেড করে।
@Entity
public class Employee {
@EmbeddedId
private EmployeeId id;
private String name;
private String position;
// Getters এবং Setters
}
@Embeddable
public class EmployeeId {
private int departmentId;
private int employeeNumber;
// Getters, Setters, hashCode, and equals
}
@Entity
public class Employee {
@EmbeddedId
private EmployeeId id;
private String name;
private String position;
// Getters এবং Setters
}
public interface EmployeeRepository extends JpaRepository<Employee, EmployeeId> {
}
@Autowired
private EmployeeRepository employeeRepository;
public void saveEmployee() {
EmployeeId id = new EmployeeId();
id.setDepartmentId(1);
id.setEmployeeNumber(101);
Employee employee = new Employee();
employee.setId(id);
employee.setName("John Doe");
employee.setPosition("Manager");
employeeRepository.save(employee);
}
public Employee findEmployee(int departmentId, int employeeNumber) {
EmployeeId id = new EmployeeId();
id.setDepartmentId(departmentId);
id.setEmployeeNumber(employeeNumber);
return employeeRepository.findById(id).orElse(null);
}
Spring ORM-এ @Embeddable এবং @EmbeddedId অ্যানোটেশন জটিল ডেটাবেস স্ট্রাকচার যেমন কম্পোজিট প্রাইমারি কি ব্যবস্থাপনার জন্য অপরিহার্য। এগুলোর মাধ্যমে জটিলতা হ্রাস পায় এবং কোড স্ট্রাকচার আরও পরিষ্কার হয়।
Composite Key হলো একটি ডেটাবেস টেবিলের জন্য একাধিক কলামের সমন্বয়ে তৈরি প্রাইমারি কী (Primary Key)। এটি তখন ব্যবহার করা হয় যখন একটি মাত্র কলাম প্রাইমারি কী হিসেবে যথেষ্ট নয়। স্প্রিং ORM-এ JPA (Java Persistence API) ব্যবহার করে সহজেই Composite Keys পরিচালনা করা যায়।
import jakarta.persistence.Embeddable;
import java.io.Serializable;
@Embeddable
public class EmployeeId implements Serializable {
private int departmentId;
private int employeeNumber;
// Default Constructor
public EmployeeId() {}
// Parameterized Constructor
public EmployeeId(int departmentId, int employeeNumber) {
this.departmentId = departmentId;
this.employeeNumber = employeeNumber;
}
// Getters and Setters
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public int getEmployeeNumber() {
return employeeNumber;
}
public void setEmployeeNumber(int employeeNumber) {
this.employeeNumber = employeeNumber;
}
// Override equals() and hashCode() methods
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EmployeeId that = (EmployeeId) o;
return departmentId == that.departmentId && employeeNumber == that.employeeNumber;
}
@Override
public int hashCode() {
return Objects.hash(departmentId, employeeNumber);
}
}
ব্যাখ্যা:
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.IdClass;
@Entity
@IdClass(EmployeeId.class)
public class Employee {
@Id
private int departmentId;
@Id
private int employeeNumber;
private String name;
private String position;
// Default Constructor
public Employee() {}
// Parameterized Constructor
public Employee(int departmentId, int employeeNumber, String name, String position) {
this.departmentId = departmentId;
this.employeeNumber = employeeNumber;
this.name = name;
this.position = position;
}
// Getters and Setters
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public int getEmployeeNumber() {
return employeeNumber;
}
public void setEmployeeNumber(int employeeNumber) {
this.employeeNumber = employeeNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
ব্যাখ্যা:
Employee
টেবিলের প্রাইমারি কী EmployeeId ক্লাসের সাথে ম্যাপ করা হয়েছে।import org.springframework.data.jpa.repository.JpaRepository;
public interface EmployeeRepository extends JpaRepository<Employee, EmployeeId> {
}
ব্যাখ্যা:
EmployeeId
কে Key Type হিসেবে ব্যবহার করা হয়েছে।import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public void saveEmployee(Employee employee) {
employeeRepository.save(employee);
}
public Employee getEmployeeById(EmployeeId employeeId) {
return employeeRepository.findById(employeeId).orElse(null);
}
}
ব্যাখ্যা:
EmployeeId employeeId = new EmployeeId(1, 101);
Employee employee = new Employee(1, 101, "John Doe", "Developer");
employeeService.saveEmployee(employee);
EmployeeId employeeId = new EmployeeId(1, 101);
Employee employee = employeeService.getEmployeeById(employeeId);
System.out.println("Employee Name: " + employee.getName());
Read more